package de.derhess.projects.pkr.component
{
	import de.derhess.projects.pkr.models.LawyerInstanceCost;
	
	import mx.binding.utils.BindingUtils;
	import mx.events.FlexEvent;
	import mx.events.PropertyChangeEvent;
	import mx.states.RemoveChild;
	import mx.states.State;
	
	import spark.components.Button;
	import spark.components.CheckBox;
	import spark.components.Label;
	import spark.components.supportClasses.SkinnableComponent;
	
	
	/**
	 * Lawyer Instance Cost Screen
	 * 
	 * 
	 * @author Florian Weil [derhess.de, Deutschland]
	 * @see http://blog.derhess.de
	 * 
	 */
	[SkinState("lawyerFirstInstance")]
	[SkinState("lawyer")]
	[SkinState("enemy")]
	public class LawyerInstance extends SkinnableComponent
	{
		//--------------------------------------------------------------------------
		//
		//  Class variables
		//
		//--------------------------------------------------------------------------
		private static const DEFAULT_HEIGHT:Number = 200;
		private static const DEFAULT_WIDTH:Number = 200;
		
		public static const STATE_LAWYER:String = "lawyer";
		public static const STATE_LAWYER_FIRST_INSTANCE:String = "lawyerFirstInstance";
		public static const STATE_ENEMY:String = "enemy";
		//--------------------------------------------------------------------------
		//
		//  Variables
		//
		//--------------------------------------------------------------------------
		
		
		//--------------------------------------------------------------------------
		//
		//  Initialization
		//
		//--------------------------------------------------------------------------
		public function LawyerInstance()
		{
			
		}
		
		override protected function createChildren():void
		{
			super.createChildren();
			createStates();
		}
		
		private function createStates():void
		{
			// STATE_LAWYER_FIRST_INSTANCE
			var state1:State = new State();
			state1.name = STATE_LAWYER_FIRST_INSTANCE;
			
			// STATE_LAWYER
			var state2:State = new State();
			state2.name = STATE_LAWYER;
			
			//STATE_ENEMY
			var state3:State = new State();
			state3.name = STATE_ENEMY;
			//var remove: = new RemoveChild(imputeSumLabel);
			//state3.overrides.push(remove);
			
			
			//states = new Array(state1,state2,state3);
			states.push(state1,state2,state3);
			currentState = STATE_LAWYER;
		}
		
		public function shitYourState():void
		{
			currentState = STATE_ENEMY;
		}
		
		//--------------------------------------------------------------------------
		//
		//  Properties
		//
		//--------------------------------------------------------------------------
		
		//----------------------------------
		//  Visual properties
		//----------------------------------
		
		[SkinPart(required="true")] public var litigationFeeBtn:Button;
		[SkinPart(required="true")] public var litigationFeeLabel:Label;
		
		[SkinPart(required="true")] public var riseFeeBtn:Button;
		[SkinPart(required="true")] public var riseFeeLabel:Label;
		
		
		[SkinPart(required="true")] public var appointmentBtn:Button;
		[SkinPart(required="true")] public var appointmentLabel:Label;
		
		[SkinPart(required="true")]	public var conciliationBtn:Button;
		[SkinPart(required="true")]	public var conciliationCheck:CheckBox;
		[SkinPart(required="true")]	public var conciliationLabel:Label;
		
		[SkinPart(required="true")] public var expensesBtn:Button;
		[SkinPart(required="true")]	public var otherCostBtn:Button;

		
		[SkinPart(required="true")]	public var vatBtn:Button;
		[SkinPart(required="true")]	public var vatLabel:Label;
		
		[SkinPart(required="true")]	public var sumLabel:Label;
		[SkinPart(required="true")]	public var imputeSumLabel:Label;
		
		//----------------------------------
		//  Data properties
		//----------------------------------
		private var _dataModel:LawyerInstanceCost;
		private var dataModelChanged:Boolean = false;
		/**
		 * This is dataModel
		 */
		public function get dataModel():LawyerInstanceCost
		{
			return _dataModel;
		}	
		/*
		* @private
		*/
		public function set dataModel(value:LawyerInstanceCost):void
		{
			if(value && (_dataModel != value)) {
				
				// removeListener from the old data object and add the listener to the new one
				if(_dataModel) {
					this.dataModel.litigationFee.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE,handleNewVAT);
					this.dataModel.riseFee.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE,handleNewVAT);
					this.dataModel.appointmentFee.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE,handleNewVAT);
					this.dataModel.conciliationFee.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE,handleNewVAT);
					this.dataModel.expenses.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE,handleNewVAT);
					this.dataModel.otherCost.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE,handleNewVAT);
					
					this.dataModel.vat.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE,handleNewSum);
				}
				
				_dataModel = value;
				
				// Add Event Listener maybe in commit Property function for performance
				this.dataModel.litigationFee.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,handleNewVAT);
				this.dataModel.riseFee.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,handleNewVAT);
				this.dataModel.appointmentFee.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,handleNewVAT);
				this.dataModel.conciliationFee.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,handleNewVAT);
				this.dataModel.expenses.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,handleNewVAT);
				this.dataModel.otherCost.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,handleNewVAT);
				
				this.dataModel.vat.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,handleNewSum);
				
				
				dataModelChanged = true;
				invalidateProperties();
			}
		}
		
		private var lawyerFeeChanged:Boolean = false;
		private var _lawyerFee:Number = 0;
		/**
		 * This is lawyerFee
		 */
		public function get lawyerFee():Number
		{
			return _lawyerFee;
		}
		
		/*
		* @private
		*/
		public function set lawyerFee(value:Number):void
		{
			if(_lawyerFee != value) {
				lawyerFeeChanged = true;
				_lawyerFee = value;
				invalidateProperties();
			}
		}
		
		
		
		private var litigationFeeFactorChanged:Boolean = false;
		private var _litigationFeeFactor:Number = 0;
		/**
		 * This is litigationFeeFactor
		 */
		public function get litigationFeeFactor():Number
		{
			return _litigationFeeFactor;
		}
		
		/*
		* @private
		*/
		public function set litigationFeeFactor(value:Number):void
		{
			if(_litigationFeeFactor != value) {
				litigationFeeFactorChanged = true;
				_litigationFeeFactor = value;
				invalidateProperties();
			}
		}
		
		
		private var riseFeeFactorChanged:Boolean = false;
		private var _riseFeeFactor:Number = 0;
		/**
		 * This is riseFeeFactor
		 */
		public function get riseFeeFactor():Number
		{
			return _riseFeeFactor;
		}
		
		/*
		* @private
		*/
		public function set riseFeeFactor(value:Number):void
		{
			if(_riseFeeFactor != value) {
				riseFeeFactorChanged = true;
				_riseFeeFactor = value;
				invalidateProperties();
			}
		}
		
		
		private var appointmentFeeFactorChanged:Boolean = false;
		private var _appointmentFeeFactor:Number = 0;
		/**
		 * This is appointmentFeeFactor
		 */
		public function get appointmentFeeFactor():Number
		{
			return _appointmentFeeFactor;
		}
		
		/*
		* @private
		*/
		public function set appointmentFeeFactor(value:Number):void
		{
			if(_appointmentFeeFactor != value) {
				appointmentFeeFactorChanged = true;
				_appointmentFeeFactor = value;
				invalidateProperties();
			}
		}
		
		private var conciliationFeeFactorChanged:Boolean = false;
		private var _conciliationFeeFactor:Number = 0;
		/**
		 * This is conciliationFeeFactor
		 */
		public function get conciliationFeeFactor():Number
		{
			return _conciliationFeeFactor;
		}
		
		/*
		* @private
		*/
		public function set conciliationFeeFactor(value:Number):void
		{
			if(_conciliationFeeFactor != value) {
				conciliationFeeFactorChanged = true;
				_conciliationFeeFactor = value;
			}
		}
		
		
		private var expensesChanged:Boolean = false;
		private var _expenses:Number = 0;
		/**
		 * This is expenses
		 */
		public function get expenses():Number
		{
			return _expenses;
		}
		
		/*
		* @private
		*/
		public function set expenses(value:Number):void
		{
			if(_expenses != value) {
				expensesChanged = true;
				_expenses = value;
				invalidateProperties();
			}
		}
		
		
		private var otherCostsChanged:Boolean = false;
		private var _otherCosts:Number = 0;
		/**
		 * This is otherCosts
		 */
		public function get otherCosts():Number
		{
			return _otherCosts;
		}
		
		/*
		* @private
		*/
		public function set otherCosts(value:Number):void
		{
			if(_otherCosts != value) {
				otherCostsChanged = true;
				_otherCosts = value;
				invalidateProperties();
			}
		}
		
		
		private var rateVATChanged:Boolean = false;
		private var _rateVAT:Number = 0;
		/**
		 * This is rateVAT
		 */
		public function get rateVAT():Number
		{
			return _rateVAT;
		}
		
		/*
		* @private
		*/
		public function set rateVAT(value:Number):void
		{
			if(_rateVAT != value) {
				rateVATChanged = true;
				_rateVAT = value;
				invalidateProperties();
			}
		}
		
		
		//--------------------------------------------------------------------------
		//
		//  Additional getters and setters
		//
		//--------------------------------------------------------------------------
		
		
		
		//--------------------------------------------------------------------------
		//
		//  Methods
		//
		//--------------------------------------------------------------------------
		override protected function measure():void
		{
			super.measure();
			measuredMinHeight = measuredHeight = DEFAULT_HEIGHT;
			measuredMinWidth = measuredWidth = DEFAULT_WIDTH;
		}
		
		override protected function commitProperties():void 
		{
			super.commitProperties();
			
			if(dataModelChanged) {
				this.dataModel.litigationFee.baseValue = lawyerFee;
				this.dataModel.litigationFee.factor = litigationFeeFactor;
				this.dataModel.appointmentFee.factor = appointmentFeeFactor;
				this.dataModel.appointmentFee.baseValue = lawyerFee;
				this.dataModel.riseFee.baseValue = lawyerFee;
				this.dataModel.riseFee.factor = riseFeeFactor;
				this.dataModel.conciliationFee.baseValue = lawyerFee;
				
				this.dataModel.vat.percentage = rateVAT;
				
				this.dataModel.expenses.sum = expenses;
				this.dataModel.otherCost.sum = otherCosts;
				dataModelChanged = false;
			}
			
			if(lawyerFeeChanged && dataModel) {
				this.dataModel.litigationFee.baseValue = lawyerFee;
				this.dataModel.appointmentFee.baseValue = lawyerFee;
				this.dataModel.conciliationFee.baseValue = lawyerFee;
				this.dataModel.riseFee.baseValue = lawyerFee;
				lawyerFeeChanged = false;
			}
			
			if(litigationFeeFactorChanged && dataModel) {
				this.dataModel.litigationFee.factor = litigationFeeFactor;
				litigationFeeFactorChanged = false;
			}
			
			if(riseFeeFactorChanged && dataModel) {
				this.dataModel.riseFee.factor = riseFeeFactor;
				riseFeeFactorChanged = false;
			}
			
			if(appointmentFeeFactorChanged && dataModel) {
				this.dataModel.appointmentFee.factor = appointmentFeeFactor;
				appointmentFeeFactorChanged = false;
			}
			
			if(expensesChanged && dataModel) {
				this.dataModel.expenses.sum = expenses;
				expensesChanged = false;
			}
			
			if(otherCostsChanged && dataModel) {
				this.dataModel.otherCost.sum = otherCosts;
				otherCostsChanged = false;
			}
			
			if(rateVATChanged && dataModel) {
				this.dataModel.vat.percentage = rateVAT;
				rateVATChanged = false;
			}
		}
		
		override protected function updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void
		{
			super.updateDisplayList(unscaledWidth,unscaledHeight);
		}
		
		override protected function getCurrentSkinState():String {
			return currentState;
		}
		
		override protected function partAdded(partName:String,instance:Object):void
		{
			
		}
		
		override protected function partRemoved(partName:String,instance:Object):void
		{
			
		}
		
		//----------------------------------
		//  Updating Text Labels
		//----------------------------------
		private function updateLabels():void
		{
			if(dataModel) {
				litigationFeeBtn.label = dataModel.litigationFee.factor.toString();
				litigationFeeLabel.text = dataModel.litigationFee.sum.toString();
				
				riseFeeBtn.label = dataModel.riseFee.factor.toString();
				riseFeeLabel.text = dataModel.riseFee.sum.toString();
				
				if(imputeSumLabel)
					imputeSumLabel.text = dataModel.imputeSum.sum.toString();
				
				appointmentBtn.label = dataModel.appointmentFee.factor.toString();
				appointmentLabel.text = dataModel.appointmentFee.sum.toString();
				
				if(conciliationBtn)
					conciliationBtn.label = dataModel.conciliationFee.factor.toString();
				conciliationLabel.text = dataModel.conciliationFee.sum.toString();
				
				expensesBtn.label = dataModel.expenses.sum.toString();
				otherCostBtn.label = dataModel.otherCost.sum.toString();
				
				vatBtn.label = dataModel.vat.percentage.toString();
				vatLabel.text = dataModel.vat.sum.toString();
				
				sumLabel.text = dataModel.sum.toString();
			}
		}
		
	
		
		//--------------------------------------------------------------------------
		//
		//  API
		//
		//--------------------------------------------------------------------------
		
		
		//--------------------------------------------------------------------------
		//
		//  Eventhandling
		//
		//--------------------------------------------------------------------------
		private function handleNewVAT(e:PropertyChangeEvent):void
		{
			if(currentState == STATE_LAWYER_FIRST_INSTANCE) {
				var tImputeSum:Number = (this.dataModel.litigationFee.sum + this.dataModel.riseFee.sum) / 2;
				
				if(tImputeSum > 0.75)
					this.dataModel.imputeSum.sum = this.dataModel.litigationFee.sum * 0.75;
				else
					this.dataModel.imputeSum.sum = tImputeSum;
			} else {
				this.dataModel.imputeSum.sum = 0;
			}
			
			
			var tSum:Number = dataModel.litigationFee.sum + dataModel.riseFee.sum - dataModel.imputeSum.sum + dataModel.appointmentFee.sum + dataModel.conciliationFee.sum + dataModel.expenses.sum + dataModel.otherCost.sum;
			this.dataModel.vat.baseValue = tSum;
		}
		
		
		private function handleNewSum(e:PropertyChangeEvent):void
		{
			this.dataModel.sum = dataModel.vat.sum + dataModel.vat.baseValue;
			updateLabels();
		}
		
		//--------------------------------------------------------------------------
		//
		//  Broadcasting
		//
		//--------------------------------------------------------------------------
		
		
	}
}
